404.継承+1配列で2種類を管理

ポリモーフィズムの力!異なる型を1つの配列で統一的に扱います。

p5.js oop
Learning OOP Object Oriented Programming

これがオブジェクト指向の真髄!ポリモーフィズム(多態性)です。

1つの配列で異なる型を管理

let objs = [];

// CircleもRectも同じ配列に入れる
objs.push(new Circle());
objs.push(new Rect());

統一的な処理

for (let obj of objs) {
  obj.update(); // 共通のupdateを呼ぶ
  obj.display(); // 各クラスの固有displayが呼ばれる
}

403との比較

403 404
2つの配列 objs, objs2 1つの配列 objs
ループも2回 ループは1回
型ごとに処理を書く 統一的に処理

ポリモーフィズムとは

「同じメソッド呼び出し(display())でも、オブジェクトの型によって異なる動作をする」

これにより、新しい種類を追加しても、ループ処理を変更する必要がありません。

View Source Code

let W, H, PW, PH;
const PADDING_RATIO = 0.2;
const MAX_SPEED = 10;

let objs = [];

const MAX = 100;

class AbstractShape {
  constructor() {
    this.pos = {
      x: random(width),
      y: random(height),
    };
    this.speed = {
      x: (Math.random() - 0.5) * MAX_SPEED,
      y: (Math.random() - 0.5) * MAX_SPEED,
    };
    this.acceleration = 0.1;
  }

  update() {
    this.pos.x += this.speed.x;
    this.pos.y += this.speed.y;

    if (this.pos.x < 0 + PW) {
      this.speed.x += this.acceleration;
    } else if (this.pos.x > W - PW) {
      this.speed.x -= this.acceleration;
    }

    if (this.pos.y < 0 + PH) {
      this.speed.y += this.acceleration;
    } else if (this.pos.y > H - PH) {
      this.speed.y -= this.acceleration;
    }
  }

  display() {
    // implement in subclass
  }
}

class Circle extends AbstractShape {
  display() {
    stroke(0);
    fill(0);
    ellipse(this.pos.x, this.pos.y, 10, 10);
    // text(["1:", Math.floor(this.pos.x), Math.floor(this.pos.y)], this.pos.x + 10, this.pos.y + 10);
  }
}

class Rect extends AbstractShape {
  display() {
    stroke(0);
    fill(0);
    rectMode(CENTER);
    rect(this.pos.x, this.pos.y, 10, 10);
    // text(["2:", Math.floor(this.pos.x), Math.floor(this.pos.y)], this.pos.x + 20, this.pos.y + 20);
  }
}

// main

function setup() {
  createCanvas((W = windowWidth), (H = windowHeight));
  PW = W * PADDING_RATIO;
  PH = H * PADDING_RATIO;

  for (let i = 0; i < MAX; i++) {
    objs.push(new Circle());
  }
  for (let i = 0; i < MAX; i++) {
    objs.push(new Rect());
  }
}

function draw() {
  background(255);

  for (let i = 0; i < objs.length; i++) {
    const obj = objs[i];
    obj.update();
  }

  for (let i = 0; i < objs.length; i++) {
    const obj = objs[i];
    obj.display();
  }
}